package com.kingmed.kmss.bpmn.modules.backup.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kingmed.kmss.bpmn.flow.helper.ProcessHelper;
import com.kingmed.kmss.bpmn.modules.backup.model.BizApprovalStatus;
import com.kingmed.kmss.bpmn.modules.backup.model.BizApprovalTrail;
import com.kingmed.kmss.bpmn.modules.backup.service.BizApprovalStatusService;
import com.kingmed.kmss.bpmn.modules.backup.service.BizApprovalTrailService;
import com.kingmed.kmss.bpmn.flow.service.custom.ProcessInstanceService;
import com.kingmed.kmss.bpmn.flow.service.base.BpmCustomServiceImpl;
import com.kingmed.kmss.common.bo.bpmn.BpmnBO;
import com.kingmed.kmss.common.bo.bpmn.ProcessInstanceStatusBO;
import com.kingmed.kmss.common.bo.bpmn.ProcessStarterBO;
import com.kingmed.kmss.common.constant.bpmn.ProcessConstant;
import com.kingmed.kmss.common.dto.admin.ums.LoginUserDTO;
import com.kingmed.kmss.common.enums.base.code.ResultCode;
import com.kingmed.kmss.common.qc.bpmn.ListProcessInstanceQc;
import com.kingmed.kmss.common.qc.bpmn.MyTaskQC;
import com.kingmed.kmss.common.satoken.LoginHelper;
import com.kingmed.kmss.common.utils.MessageUtils;
import com.kingmed.kmss.common.vo.CommonPage;
import com.kingmed.kmss.common.vo.CommonResponse;
import com.kingmed.kmss.common.vo.CommonResponseHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 需补充审批功能所需要的流程类接口，包括流程启动，流程终止，流程历史等接口
 * </p>
 */
@RestController
@RequestMapping("/ext")
@Api(tags = "bpmn-流程定义和流程实例管理")
@Slf4j
public class ProcessController {

	@Autowired
	private BpmCustomServiceImpl customService;

	@Autowired
    BizApprovalStatusService approvalStatusSvc;

	@Autowired
    BizApprovalTrailService bizTrailSvc;

	@Autowired
	ProcessHelper procHelper;

	@Autowired
	private ProcessInstanceService processInstanceService;

	/**
	 * 前端没用到
	 * 入参是bo processStarterBO，可以改成仅通过key来开启流程实例
	 * 测试数据processKey=oneTaskProcess，必须要传token，以便获取user和group信息
	 * 备注：某些flowable的原生model，例如ProcessDefinition，直接在controller返回时会发生数据转换异常，建议copy到bo或者dto，再放入CommonResponse
	 */
	@ApiOperation("根据ProcessDefinitionKey开启一个流程实例")
	@PostMapping(value = "/process/start")
	public CommonResponse<BpmnBO> startProcess(@RequestBody ProcessStarterBO procStarter) {
		log.info("startProcess(): {}", procStarter);
		BpmnBO bpmBO = new BpmnBO();
		if (StrUtil.isBlank(procStarter.getProcDefKey())) {
			return CommonResponseHelper.bpmnFailed(ResultCode.BPMN_PROCESS_KEY_FAILED, bpmBO);
		}

		if (StringUtils.isEmpty(procStarter.getStartUserId())) {

			// 获取当前用户
			LoginUserDTO loginUser = LoginHelper.getLoginUser();

			if (loginUser == null || loginUser.getUsername() == null) {
				return CommonResponseHelper.fail(MessageUtils.message("userNotLoggedIn"));
			}
			// 这里放的userid实际是username，千万注意！！
			procStarter.setStartUserId(loginUser.getUsername());
		}

		bpmBO = customService.startProcessInstance(procStarter);

		return CommonResponseHelper.success(bpmBO);
	}

	/**
	 * 前端用到（我已审批）
	 * @param param
	 * @return
	 */
	@ApiOperation("我已审批列表")
	@PostMapping(value = "/process/approved/mine")
	public CommonResponse<CommonPage<BizApprovalStatus>> myApprovedProcess(@RequestBody MyTaskQC param) {

		if (StringUtils.isEmpty(param.getUserId())) {
			LoginUserDTO loginUser = LoginHelper.getLoginUser();

			if (loginUser == null || loginUser.getUsername() == null) {
				return CommonResponseHelper.fail(MessageUtils.message("userNotLoggedIn"));
			}
			// param.setCurrApprover(loginUser.getUsername());
			param.setUserId(loginUser.getUsername());

		}

		List<BizApprovalTrail> myCompleteBusinesses = bizTrailSvc.getMyCompleteProcesses(param.getBizType(),
				param.getUserId());
		List<String> procInstIds = myCompleteBusinesses.stream().map(BizApprovalTrail::getProcInstId)
				.collect(Collectors.toList());
		if (CollUtil.isEmpty(procInstIds)) {
			Page<BizApprovalStatus> page = new Page<>(param.getPageNum(), param.getPageSize());
			return CommonResponseHelper.success(CommonPage.restPage(page));
		}

		Page<BizApprovalStatus> page = approvalStatusSvc.getBizApprovalStatusByBizIds(param.getBizType(),
				procInstIds, param.getCurrApprover(), param.getAuditStatus(), null, param.getPageSize(),
				param.getPageNum(), param.getStartDate(), param.getEndDate(), param.getRequestByName());
		page.getRecords().forEach(e -> {
			if (ProcessConstant.Status.REJECTED.equals(e.getCurrStatus())) {
				e.setNextApprover(e.getRequestBy());
				e.setNextApproverName(e.getRequestByName());
				e.setNextApproverDept(e.getRequestByDept());
			}
		});
		return CommonResponseHelper.success(CommonPage.restPage(page));
	}

	/**
	 * 前端用到（我提交的）
	 * @param param
	 * @return
	 */
	@ApiOperation("我已提交列表")
	@PostMapping(value = "/process/mySubmitted")
	public CommonResponse<CommonPage<BizApprovalStatus>> mySubmitted(@RequestBody MyTaskQC param) {

		// CommonPage<TaskBO> tasks = bpmService.getTasksByUser(param.getUserId(),
		// param.getBizType(), param.getPageNum(), param.getPageSize());

		if (StringUtils.isEmpty(param.getUserId())) {
			LoginUserDTO loginUser = LoginHelper.getLoginUser();

			if (loginUser == null || loginUser.getUsername() == null) {
				return CommonResponseHelper.fail(MessageUtils.message("userNotLoggedIn"));
			}
			// param.setCurrApprover(loginUser.getUsername());
			param.setUserId(loginUser.getUsername());

		}

		Page<BizApprovalStatus> page = bizTrailSvc.getMySubmitProcesses(param.getBizType(),
				param.getUserId(), param.getCurrApprover(), param.getAuditStatus(), param.getPageNum(),
				param.getPageSize(), param.getStartDate(), param.getEndDate(), param.getRequestByName());
		
		page.getRecords().forEach(e -> {
			if (ProcessConstant.Status.REJECTED.equals(e.getCurrStatus())) {
				e.setNextApprover(e.getRequestBy());
				e.setNextApproverName(e.getRequestByName());
				e.setNextApproverDept(e.getRequestByDept());
			}
		});
		
		return CommonResponseHelper.success(CommonPage.restPage(page));
	}

	/**
	 * 前端用到（流程图示）
	 * @param listProcessInstanceQc
	 * @return
	 */
	@Validated
    @ApiOperation("获取审批流程实例列表")
    @PostMapping(value = "/process/listProcessInstance")
    public CommonResponse<List<ProcessInstanceStatusBO>> listProcessInstance(@RequestBody ListProcessInstanceQc listProcessInstanceQc) {
        List<ProcessInstanceStatusBO> processInstanceStatusBOList = processInstanceService.listProcessInstanceStatusBO(listProcessInstanceQc.getBusinessId(), listProcessInstanceQc.getBusinessType());
        return CommonResponseHelper.success(processInstanceStatusBOList);
    }
}
